package com.lhh.ptrrv.library;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.RelativeLayout;

import com.lhh.ptrrv.library.footer.loadmore.BaseLoadMoreView;
import com.lhh.ptrrv.library.footer.loadmore.DefaultLoadMoreView;
import com.lhh.ptrrv.library.header.Header;
import com.lhh.ptrrv.library.impl.PrvInterface;
import com.lhh.ptrrv.library.util.PullToRefreshRecyclerViewUtil;
import com.nineoldandroids.view.ViewHelper;

/**
 * Created by linhonghong on 2015/11/11.
 */
public class PullToRefreshRecyclerViewCustom extends CustomSwipeRefreshLayout implements PrvInterface {

    //    private static final String TAG = "PTRRV";
    //内部的RecyclerView
    private RecyclerView mRecyclerView;

    //root header
    private Header mRootHeader;

    //main view,contain footer，header etc.
    private RelativeLayout mRootRelativeLayout;

    //header
    private View mHeader;
    //空值时显示的view
    private View mEmptyView;

    // 加载更多的数量 默认为default = 10
    private int mLoadMoreCount = 10;

    private int mCurScroll;
    //是否支持下拉加载 默认不支持
    private boolean mIsSwipeEnable = false;
    //加载更多的基类view 自定义样式时可以这么做
    private BaseLoadMoreView mLoadMoreFooter;

    private PagingableListener mPagingableListener;

    private AdapterObserver mAdapterObserver;
    //是否正在加载数据
    private boolean isLoading = false;
    //是否还有更多的数据 默认有更多的数据
    private boolean hasMoreItems = true;
    //该自定义view的值 用来替换RV的滚动事件监听
    private PullToRefreshRecyclerViewCustom.OnScrollListener mOnScrollLinstener;

    private InterOnScrollListener mInterOnScrollListener;

    private PullToRefreshRecyclerViewUtil mPtrrvUtil;


    public PullToRefreshRecyclerViewCustom(Context context) {
        this(context, null);
    }

    public PullToRefreshRecyclerViewCustom(Context context, AttributeSet attrs) {
        super(context, attrs);
        //初始化数据
        this.setup();
    }

    /**
     * main
     */
    private void setup() {
        //设置默认数据
        setupExtra();
        //初始化view
        initView();
        //设置监听器
        setLinster();
    }

    public void setRefreshing(boolean refreshing) {
        super.setRefreshing(refreshing);
    }

    /**
     * initView
     */
    private void initView() {
        //获取RV承载的根目录上
        mRootRelativeLayout = (RelativeLayout) LayoutInflater.from(getContext()).inflate(R.layout.ptrrv_root_view, null);
        //把系统的下拉刷新布局 添加多之前的根目录 嵌入RV
        this.addView(mRootRelativeLayout);
        //设置下拉旋转颜色
        this.setColorSchemeResources(R.color.swap_holo_green_bright, R.color.swap_holo_bule_bright,
                R.color.swap_holo_green_bright, R.color.swap_holo_bule_bright);
        //获取RV
        mRecyclerView = (RecyclerView) mRootRelativeLayout.findViewById(R.id.recycler_view);
        //requestLayout()是很昂贵的，所以如当不是瀑布流时，设置这个可以避免重复的增删造成额外的浪费资源
        mRecyclerView.setHasFixedSize(true);
        //设置是否支持下拉 默认不支持 默认值为false
        if (!mIsSwipeEnable) {
            this.setEnabled(false);
        }

    }

    /**
     * Init
     */
    private void setupExtra() {
        //isLoading 默认没有正在加载
        isLoading = false;
        //hasMoreItems 默认还有更多的item数据
        hasMoreItems = true;
        //PullToRefreshRecyclerViewUtil的工具类 主要返回第一个可见pisition和最后一个position这种，当然修改后这个被弃用了
        mPtrrvUtil = new PullToRefreshRecyclerViewUtil();
    }

    /**
     * 设置监听器
     */
    private void setLinster() {
        //初始化RecyclerView的滚动监听器
        mInterOnScrollListener = new InterOnScrollListener();
        mRecyclerView.addOnScrollListener(mInterOnScrollListener);
    }

    @Override
    public void setOnRefreshComplete() {
        this.setRefreshing(false);
    }

    @Override
    public void setOnLoadMoreComplete() {
        setHasMoreItems(false);
    }

    @Override
    public void setPagingableListener(PullToRefreshRecyclerViewCustom.PagingableListener pagingableListener) {
        mPagingableListener = pagingableListener;
    }

    /**
     * 设置空的视图
     *
     * @param emptyView
     */
    @Override
    public void setEmptyView(View emptyView) {
        if (mEmptyView != null) {
            mRootRelativeLayout.removeView(mEmptyView);
        }
        mEmptyView = emptyView;
    }

    /**
     * 设置RV的适配器 并添加适配器的数据监听
     *
     * @param adapter
     */
    @Override
    public void setAdapter(RecyclerView.Adapter adapter) {
        mRecyclerView.setAdapter(adapter);
        //初始化数据适配器监听
        if (mAdapterObserver == null) {
            mAdapterObserver = new AdapterObserver();
        }
        //注册
        if (adapter != null) {
            adapter.registerAdapterDataObserver(mAdapterObserver);
            mAdapterObserver.onChanged();
        }
    }

    /**
     * 跳转到某个postion
     *
     * @param position
     */
    @Override
    public void scrollToPosition(int position) {
        mRecyclerView.scrollToPosition(position);
    }

    /**
     * 平滑的跳转到某个postion
     *
     * @param position
     */
    @Override
    public void smoothScrollToPosition(int position) {
        mRecyclerView.smoothScrollToPosition(position);
    }

    /**
     * 添加头
     *
     * @param view
     */
    @Override
    public void addHeaderView(View view) {
        //2015.11.17 finish method
        if (mHeader != null) {
            mRootRelativeLayout.removeView(mHeader);
        }

        mHeader = view;

        if (mHeader == null) {
            return;
        }
        //View.getViewTreeObserver().addOnGlobalLayoutListener可以获得宽度和高度
        mHeader.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout() {
                //注销监听
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
                    mHeader.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                } else {
                    mHeader.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                }

                if (getRecyclerView() == null || mHeader == null) {
                    return;
                }
                if (mRootHeader == null) {
                    mRootHeader = new Header();
                }
                mRootHeader.setHeight(mHeader.getMeasuredHeight());
                getRecyclerView().removeItemDecoration(mRootHeader);
                getRecyclerView().addItemDecoration(mRootHeader);
                getRecyclerView().getAdapter().notifyDataSetChanged();
            }
        });

        mRootRelativeLayout.addView(mHeader);
    }

    @Override
    public void removeHeader() {
        if (mRootHeader != null) {
            getRecyclerView().removeItemDecoration(mRootHeader);
            mRootHeader = null;
        }
        if (mHeader != null) {
            mRootRelativeLayout.removeView(mHeader);
            mHeader = null;
        }
    }

    @Override
    public void setFooter(View view) {
        // now is empty, you can do in extra adapter
    }

    //设置加载数据时候的视图
    @Override
    public void setLoadMoreFooter(BaseLoadMoreView loadMoreFooter) {
        mLoadMoreFooter = loadMoreFooter;
    }

    //获取加载数据时候的视图
    @Override
    public BaseLoadMoreView getLoadMoreFooter() {
        return mLoadMoreFooter;
    }

    //添加外部的滚动监听器扩展
    @Override
    public void addOnScrollListener(PullToRefreshRecyclerViewCustom.OnScrollListener onScrollLinstener) {
        mOnScrollLinstener = onScrollLinstener;
    }

    /**
     * 获取RV的布局管理器
     *
     * @return
     */
    @Override
    public RecyclerView.LayoutManager getLayoutManager() {
        if (mRecyclerView != null) {
            return mRecyclerView.getLayoutManager();
        }
        return null;
    }

    /**
     * 废弃掉 采用另外的形式
     *
     * @param hasMoreItems
     * @param needSetSelection
     */
    @Deprecated
    @Override
    public void onFinishLoading(boolean hasMoreItems, boolean needSetSelection) {

        if (getLayoutManager() == null) {
            return;
        }

        if (!hasMoreItems && mLoadMoreFooter != null) {
            //if it's last line, minus the extra height of loadmore
            mCurScroll = mCurScroll - mLoadMoreFooter.getLoadMorePadding();
        }
        //如果items太短，不展示加载页面
        // if items is too short, don't show loadingview
        if (getLayoutManager().getItemCount() < mLoadMoreCount) {
            hasMoreItems = false;
        }
        //根据传入参数设置加载页面是否显示
        setHasMoreItems(hasMoreItems);
        //设置正在加载结束
        isLoading = false;
        //判断是否需要跳至可见的第一个item的位置
        if (needSetSelection) {
            int first = findFirstVisibleItemPosition();
            mRecyclerView.scrollToPosition(first);
        }
    }

    /**
     * 显示加载数据的进度view
     *
     * @param needSetSelection 是否需要跳转到第一位
     */
    public void showLoadView(boolean needSetSelection) {
        boolean hasMoreItems = true;
        if (getLayoutManager() == null) {
            return;
        }
        //如果items太短，不展示加载页面
        // if items is too short, don't show loadingview
        if (getLayoutManager().getItemCount() < mLoadMoreCount) {
            hasMoreItems = false;
        }
        //根据传入参数设置加载页面是否显示
        setHasMoreItems(hasMoreItems);
        //设置正在加载
        isLoading = true;
        //判断是否需要跳至可见的第一个item的位置
        if (needSetSelection) {
            int first = findFirstVisibleItemPosition();
            mRecyclerView.scrollToPosition(first);
        }
    }

    /**
     * 隐藏加载显示
     */
    public void hideShowView() {
        boolean hasMoreItems = false;
        if (getLayoutManager() == null) {
            return;
        }

        if (mLoadMoreFooter != null) {
            //if it's last line, minus the extra height of loadmore
            mCurScroll = mCurScroll - mLoadMoreFooter.getLoadMorePadding();
        }
        //如果items太短，不展示加载页面
        // if items is too short, don't show loadingview
        if (getLayoutManager().getItemCount() < mLoadMoreCount) {
            hasMoreItems = false;
        }
        //根据传入参数设置加载页面是否显示
        setHasMoreItems(hasMoreItems);
        //设置正在加载结束
        isLoading = false;
    }

    public int findFirstVisibleItemPosition() {
        return mPtrrvUtil.findFirstVisibleItemPosition(getLayoutManager());
    }

    public int findLastVisibleItemPosition() {
        return mPtrrvUtil.findLastVisibleItemPosition(getLayoutManager());
    }

    public int findFirstCompletelyVisibleItemPosition() {
        return mPtrrvUtil.findFirstCompletelyVisibleItemPosition(getLayoutManager());
    }

    @Override
    public void setSwipeEnable(boolean enable) {
        //just like extra setEnable(boolean).but it's more easy to use, like super.setEnable
        mIsSwipeEnable = enable;
        this.setEnabled(mIsSwipeEnable);
    }

    @Override
    public boolean isSwipeEnable() {
        return mIsSwipeEnable;
    }

    @Override
    public RecyclerView getRecyclerView() {
        return this.mRecyclerView;
    }

    @Override
    public void setLayoutManager(RecyclerView.LayoutManager layoutManager) {
        if (mRecyclerView != null) {
            mRecyclerView.setLayoutManager(layoutManager);
        }
    }

    @Override
    public void setLoadMoreCount(int count) {
        mLoadMoreCount = count;
    }

    @Override
    public void release() {

    }

    public void setLoadmoreString(String str) {
        if (mLoadMoreFooter != null) {
            mLoadMoreFooter.setLoadmoreString(str);
        }
    }

    /**
     * 设置还有更多的数据展示 并显示出动画
     *
     * @param hasMoreItems
     */
    private void setHasMoreItems(boolean hasMoreItems) {
//        this.hasMoreItems = hasMoreItems;
        //如果没有加载布局就使用默认的
        if (mLoadMoreFooter == null) {
            mLoadMoreFooter = new DefaultLoadMoreView(getContext(), getRecyclerView());
        }
        //如果没有数据了删除动画 如果还有展示动画
        if (!hasMoreItems) {
            //remove loadmore
            mRecyclerView.removeItemDecoration(mLoadMoreFooter);
        } else {
            //add loadmore
            mRecyclerView.removeItemDecoration(mLoadMoreFooter);
            mRecyclerView.addItemDecoration(mLoadMoreFooter);
        }
    }

    //是否滑动到底部
    public static boolean isSlideToBottom(RecyclerView recyclerView) {
        if (recyclerView == null) return false;
        if (recyclerView.computeVerticalScrollExtent() + recyclerView.computeVerticalScrollOffset()
                >= recyclerView.computeVerticalScrollRange())
            return true;
        return false;
    }

    /**
     * 滚动监听器
     */
    private class InterOnScrollListener extends RecyclerView.OnScrollListener {
        /**
         * 滚动状态改变
         *
         * @param recyclerView
         * @param newState
         */
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
            //do super before callback
            if (mOnScrollLinstener != null) {
                mOnScrollLinstener.onScrollStateChanged(recyclerView, newState);
            }
        }

        /**
         * 滚动位移发生改变
         *
         * @param recyclerView
         * @param dx
         * @param dy
         */
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            //do super before callback
            if (getLayoutManager() == null) {
                //here layoutManager is null
                return;
            }
            //计算头布局的偏移量 然后滚动时对头部进行滚动 哈哈哈——+
            mCurScroll = dy + mCurScroll;
            if (mHeader != null) {
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
                    mHeader.setTranslationY(-mCurScroll);
                } else {
                    ViewHelper.setTranslationY(mHeader, -mCurScroll);
                }
            }
            //声明第一个item、可见的item数量，item的总数量、最后可见的item
            int firstVisibleItem, visibleItemCount, totalItemCount, lastVisibleItem;
            //获取和其绑定的item总数量、其中并不包括暂时分离的和报废的，既获取的时候可见的item
            visibleItemCount = getLayoutManager().getChildCount();
            //返回绑定的适配器item的数量 既总数量
            totalItemCount = getLayoutManager().getItemCount();
            //获取第一个可见item的position
            firstVisibleItem = findFirstVisibleItemPosition();
            //sometimes ,the last item is too big so as that the screen cannot show the item fully
            //获取最后一个可见item的position
            lastVisibleItem = findLastVisibleItemPosition();
//            lastVisibleItem = mLinearLayoutManager.findLastCompletelyVisibleItemPosition();
            //判断是否可以下拉刷新
            if (mIsSwipeEnable) {
                if (findFirstCompletelyVisibleItemPosition() != 0) {
                    //here has a bug, if the item is too big , use findFirstCompletelyVisibleItemPosition will cannot swipe
                    PullToRefreshRecyclerViewCustom.this.setEnabled(false);
                } else {
                    PullToRefreshRecyclerViewCustom.this.setEnabled(true);
                }
            }
            Log.e("canScrollVertically(1)", mRecyclerView.canScrollVertically(1) + "");
            //如果总数量少于一次性加载数量 就没有必要加载了
            if (totalItemCount < mLoadMoreCount) {
                setHasMoreItems(false);
                isLoading = false;
                //1.0 没有正在加载
                //2.0 还有更多的item
                //3.0 isSlideToBottom(getRecyclerView()) 是否拉到底部
            } else if (!isLoading && hasMoreItems && !mRecyclerView.canScrollVertically(1)) {
                if (mPagingableListener != null) {
                    isLoading = true;
                    mPagingableListener.onLoadMoreItems();
                }

            }

            if (mOnScrollLinstener != null) {
                mOnScrollLinstener.onScrolled(recyclerView, dx, dy);
                mOnScrollLinstener.onScroll(recyclerView, firstVisibleItem, visibleItemCount, totalItemCount);
            }
        }

    }

    private class AdapterObserver extends RecyclerView.AdapterDataObserver {
        @Override
        public void onChanged() {
            super.onChanged();
            //adapter has change
            if (mRecyclerView == null) {
                //here must be wrong ,recyclerView is null????
                return;
            }

            RecyclerView.Adapter<?> adapter = mRecyclerView.getAdapter();
            if (adapter != null && mEmptyView != null) {
                if (adapter.getItemCount() == 0) {
                    if (mIsSwipeEnable) {
                        PullToRefreshRecyclerViewCustom.this.setEnabled(false);
                    }
                    if (mEmptyView.getParent() != mRootRelativeLayout) {
                        mRootRelativeLayout.addView(mEmptyView);
                    }
                    mEmptyView.setVisibility(View.VISIBLE);
                    mRecyclerView.setVisibility(View.GONE);
                } else {
                    if (mIsSwipeEnable) {
                        PullToRefreshRecyclerViewCustom.this.setEnabled(true);
                    }
                    mEmptyView.setVisibility(View.GONE);
                    mRecyclerView.setVisibility(View.VISIBLE);
                }
            }
        }
    }

    public interface PagingableListener {
        void onLoadMoreItems();
    }

    public interface OnScrollListener {
        void onScrollStateChanged(RecyclerView recyclerView, int newState);

        void onScrolled(RecyclerView recyclerView, int dx, int dy);
        //old-method, like listview 's onScroll ,but it's no use ,right ? by linhonghong 2015.10.29
        void onScroll(RecyclerView recyclerView, int firstVisibleItem, int visibleItemCount, int totalItemCount);
    }
}
